package cn.zxf.note.note.review;

import cn.zxf.note.common.exception.BizException;
import cn.zxf.note.common.utils.DateUtils;
import cn.zxf.note.note.note.Note;
import cn.zxf.note.note.note.NoteSupport;
import cn.zxf.note.note.review.dto.NoteReviewItemDto;
import cn.zxf.note.note.review.dto.NoteReviewListDto;
import cn.zxf.note.note.review.dto.NoteReviewTodayListDto;
import cn.zxf.note.security.UserAuthService;
import com.github.zengxf.common.utils.BeanUtils;
import com.github.zengxf.common.utils.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import jakarta.transaction.Transactional;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
public class NoteReviewService {

    @Autowired
    private NoteReviewDao dao;
    @Autowired
    private NoteReviewRepository repos;
    @Autowired
    private UserAuthService authService;
    @Autowired
    private NoteReviewSupport support;
    @Autowired
    private NoteSupport noteSupport;


    public List<NoteReviewTodayListDto> findList(Integer userId, String dateStr, Integer status) {
        authService.validate(userId);
        if (!NoteReviewStatusEnum.isNormal(status))
            BizException.of("复习计划查询状态不对");
        LocalDate date = LocalDate.parse(dateStr);

        List<NoteReviewItemDto> list = dao.findList(userId, date, status);
        Map<Integer, List<NoteReviewItemDto>> map = ListUtils.groupMap(list, NoteReviewItemDto::getTypeId);

        List<NoteReviewTodayListDto> dtoList = ListUtils.transformList(new ArrayList<>(map.entrySet()), e -> {
            List<NoteReviewItemDto> tList = e.getValue();
            NoteReviewItemDto first = tList.get(0);

            NoteReviewTodayListDto dto = new NoteReviewTodayListDto();
            BeanUtils.copyProperties(first, dto);

            dto.setNotes(ListUtils.simpleTransformList(tList, NoteReviewTodayListDto.InnerNoteDto::new));
            return dto;
        });

        return dtoList;
    }

    public String findNotReviewRecentDate(Integer userId) {
        authService.validate(userId);
        return dao.findNotReviewRecentDate(userId);
    }

    public void updateToReviewed(Integer userId, Integer id) {
        NoteReview nr = this.validate(userId, id);
        int sign = dao.updateStatus(id, NoteReviewStatusEnum.REVIEWED.code, new Date());
        if (sign > 0 && nr.getStatus() == NoteReviewStatusEnum.NORMAL_CODE) {
            int days = DateUtils.intervalDays(nr.getReviewDate());
            if (days != 0) { // 后面的复习计划时间往后或往前推
                dao.updateDateAddDays(nr.getNoteId(), nr.getId(), days);
            }
        }
    }

    public void updateToNotReviewed(Integer userId, Integer id) {
        this.validate(userId, id);
        dao.updateStatus(id, NoteReviewStatusEnum.INITIAL.code, null);
    }

    public List<NoteReviewListDto> findList(Integer userId, Integer noteId) {
        authService.validate(userId);
        return dao.findList(userId, noteId);
    }

    @Transactional
    public void resetReviewPlan(Integer userId, Integer noteId) {
        Note note = noteSupport.validateAndGet(noteId);
        authService.validate(userId, note.getUserId());
        dao.deleteNotReviewed(userId, noteId);
        support.batchInsert(userId, noteId);
    }

    private NoteReview validate(Integer userId, Integer id) {
        if (id == null)
            throw BizException.of("ID 为空");
        NoteReview obj = repos.findById(id)
                .orElseThrow(() -> BizException.of("复习计划不存在"));
        if (!NoteReviewStatusEnum.isNormal(obj.getStatus()))
            BizException.of("复习计划已取消");
        authService.validate(userId, obj.getUserId());
        return obj;
    }

}
